
#ifndef XDNS_DECODER_H
#define XDNS_DECODER_H

#include "xdns.h"
#include <string>

class XdnsData;
class XdnsHeaderInfo;
class XdnsQuestionInfo;
class XdnsResourceRecordInfo;

/*! Handle protocol decoding for both TCP and UDP. */
class XdnsDecoder
{
public:
    /*! Decode the info of DNS header section from the raw data.

        The data size of DNS header section is a constant value. It is
        defined as XDNS_HEADER_SIZE in the header file xdns-protocol.h.

        @param data The raw data used to decode.
        @param startOffset The offset of data is used to specify where
                           the base position of the header section is
                           located.
        @param header On return the decoded info.
        @return XE_Ok if success,
                XE_BadResponse if the raw data is not right.
    */
    static XdnsError DecodeHeader(const XdnsData& data,
                                  size_t startOffset,
                                  XdnsHeaderInfo& header);

    /*! Decode the info of DNS question section from the raw data.

        @param data The raw data used to decode.
        @param dataOffset The offset of the whole raw data.
        @param startOffset The offset of data is used to specify where
                           the base position of the question section is
                           located.
        @param question On return the decoded info.
        @param dataSize On return the data size of this question
                        section in the raw data.
        @return XE_Ok if success,
                XE_BadResponse if the raw data is not right.
    */
    static XdnsError DecodeQuestion(const XdnsData& data,
                                    size_t dataOffset,
                                    size_t startOffset,
                                    XdnsQuestionInfo& question,
                                    size_t& dataSize);

    /*! Decode the info of DNS resource record from the raw data.

        @param data The raw data used to decode.
        @param dataOffset The offset of the whole raw data.
        @param startOffset The offset of data is used to specify where
                           the base position of the resource record is
                           located.
        @param resourceRecord On return the decoded info.
        @param dataSize On return the data size of this resource
                        record in the raw data.
        @return XE_Ok if success,
                XE_BadResponse if the raw data is not right.
    */
    static XdnsError DecodeResourceRecord(const XdnsData& data,
                                          size_t dataOffset,
                                          size_t startOffset,
                                          XdnsResourceRecordInfo& resourceRecord,
                                          size_t& dataSize);

    /*! Decode a series of labels to a string.

        @param data The raw data used to decode.
        @param dataOffset The offset of the whole raw data.
        @param startOffset The offset of data is used to specify where
                           the base position of the first label is
                           located.
        @param value On return the decoded string.
        @param dataSize On return the data size of the labels in the
                        raw data.
        @return XE_Ok if success,
                XE_BadResponse if the raw data is not right.
    */
    static XdnsError DecodeLabels(const XdnsData& data,
                                  size_t dataOffset,
                                  size_t startOffset,
                                  std::string& value,
                                  size_t& dataSize);

private:
    XdnsDecoder();
    ~XdnsDecoder();
};

#endif  // XDNS_DECODER_H

